package com.niiwoo.civet.mobile.lanmao.handler;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.niiwoo.civet.account.dto.common.MarketingDTO;
import com.niiwoo.civet.account.enums.AccountSendPrizeStatusEnum;
import com.niiwoo.civet.account.service.AccountFundTransferDubboService;
import com.niiwoo.civet.account.service.AccountRefundOrderPushDubboService;
import com.niiwoo.civet.account.service.MarketingDubboService;
import com.niiwoo.civet.trade.dto.common.BathTransactionNotifyDTO;
import com.niiwoo.civet.trade.service.creditor.CreditorTransferConfirmDubboService;
import com.niiwoo.civet.trade.service.lend.ProjectLendDubboService;
import com.niiwoo.civet.trade.service.newRefund.RefundBankBackDubboService;
import com.niiwoo.tripod.lanmao.enums.LanMaoGatewayServiceNameEnum;
import com.niiwoo.tripod.lanmao.enums.TransactionTypeEnum;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;

/**
 * @Description 批量交易通知
 * @Author zq
 * @Date 2017/12/5
 */
@Component
@Slf4j
public class BatchAsyncTransactionNotifyHandler implements LanMaoNotifyHandler {

    private static final Logger logger = LoggerFactory.getLogger(BatchAsyncTransactionNotifyHandler.class);

    @Reference(version = "1.0.0")
    MarketingDubboService marketingDubboService;

    @Reference(version = "1.0.0")
    ProjectLendDubboService projectLendDubboService;

    @Reference(version = "1.0.0")
    AccountRefundOrderPushDubboService accountRefundOrderPushDubboService;

    @Reference(version = "1.0.0")
    RefundBankBackDubboService refundBankBackDubboService;

    @Reference(version = "1.0.0")
    AccountFundTransferDubboService accountFundTransferService;

    @Reference(version = "1.0.0")
    CreditorTransferConfirmDubboService creditorTransferConfirmDubboService;

    @Autowired
    private List<LanMaoBizNotifyHandler> handlers;

    @Override
    public boolean supports(String serviceName) {
        return LanMaoGatewayServiceNameEnum.ASYNC_TRANSACTION.name().equals(serviceName);
    }

    @Override
    public HandleResult handle(JSONObject json) {
        log.info("--批量交易-handle---start----------{}",json==null?"":json.toJSONString());
        JSONArray array = JSONArray.parseArray(json.getString("details"));
        List<String> requestNoList = new ArrayList<>();
        /**
         * 还款listDTO
         */
//        List<AsyncTransactionNotifyDTO> asyncTransactionForRefundList = new ArrayList();
        List<BathTransactionNotifyDTO> lendNotifyDTOList = new ArrayList();
        List<BathTransactionNotifyDTO> refundNotifyDTOList = new ArrayList<>();

        List<BathTransactionNotifyDTO> creditorTransferConfirmNotifyDTOList = new ArrayList();

        for (int i = 0; i < array.size(); i++) {
            JSONObject object = array.getJSONObject(i);
            BatchAsyncTransactionGatewayResponse response = object.toJavaObject(BatchAsyncTransactionGatewayResponse.class);
            if(TransactionTypeEnum.MARKETING.name().equals(response.getBizType())){
                MarketingDTO marketingDTO = new MarketingDTO();
                marketingDTO.setAsyncRequestNo(response.getAsyncRequestNo());
                marketingDTO.setSendPrizeStatusEnum(response.isBusinessSuccess() ? AccountSendPrizeStatusEnum.SEND_SUCCESS : AccountSendPrizeStatusEnum.SEND_FAILED);
                marketingDubboService.callCashPrize(marketingDTO);
                requestNoList.add(response.getAsyncRequestNo());
            } else if(TransactionTypeEnum.TENDER.name().equals(response.getBizType())){
                BathTransactionNotifyDTO lendNotifyDTO = new BathTransactionNotifyDTO();
                lendNotifyDTO.setAsyncRequestNo(response.getAsyncRequestNo());
                lendNotifyDTO.setStatus( response.getStatus());
                lendNotifyDTO.setErrorCode(response.getErrorCode());
                lendNotifyDTO.setErrorMessage(response.getErrorMessage());
                lendNotifyDTOList.add(lendNotifyDTO);
            } else if(TransactionTypeEnum.CREDIT_ASSIGNMENT.name().equals(response.getBizType())){
                BathTransactionNotifyDTO creditorTransferConfirmNotifyDTO = new BathTransactionNotifyDTO();
                creditorTransferConfirmNotifyDTO.setAsyncRequestNo(response.getAsyncRequestNo());
                creditorTransferConfirmNotifyDTO.setStatus( response.getStatus());
                creditorTransferConfirmNotifyDTO.setErrorCode(response.getErrorCode());
                creditorTransferConfirmNotifyDTO.setErrorMessage(response.getErrorMessage());
                creditorTransferConfirmNotifyDTOList.add(creditorTransferConfirmNotifyDTO);
            } else if(TransactionTypeEnum.COMPENSATORY.name().equals(response.getBizType())
                    ||TransactionTypeEnum.REPAYMENT.name().equals(response.getBizType())
                    ||TransactionTypeEnum.PLATFORM_INDEPENDENT_PROFIT.name().equals(response.getBizType())
                    ||TransactionTypeEnum.PLATFORM_SERVICE_DEDUCT.name().equals(response.getBizType())){
                BathTransactionNotifyDTO refundNotifyDTO = new BathTransactionNotifyDTO();
                BeanUtils.copyProperties(response,refundNotifyDTO);
                refundNotifyDTOList.add(refundNotifyDTO);
            } else if(TransactionTypeEnum.FUNDS_TRANSFER.name().equals(response.getBizType())){
                if (response.isBusinessSuccess()) {
                    //转账成功
                    accountFundTransferService.processSubmitFundTransferNotify(response.getAsyncRequestNo(), true);
                } else {
                    //转账失败
                    accountFundTransferService.processSubmitFundTransferNotify(response.getAsyncRequestNo(), false);
                }
            }
        }
       if(lendNotifyDTOList.size() > 0){
           try {
               CompletableFuture.runAsync(() -> projectLendDubboService.lendResultNotify(lendNotifyDTOList));
           } catch (Throwable e) {
               logger.error("放款结果通知处理异常", e);
           }
       }

       if(refundNotifyDTOList.size()>0){
            try {
                CompletableFuture.runAsync(() -> refundBankBackDubboService.bankRefundResultNotify(refundNotifyDTOList));
            } catch (Throwable e) {
                logger.error("还款结果通知处理异常", e);
            }
        }

        if(creditorTransferConfirmNotifyDTOList.size()>0){
            try {
                CompletableFuture.runAsync(() -> creditorTransferConfirmDubboService.creditorTransferConfirmResultNotify(creditorTransferConfirmNotifyDTOList));
            } catch (Throwable e) {
                logger.error("债转确认结果通知处理异常", e);
            }
        }

        HandleResult handleResult = new HandleResult();
        handleResult.setData(requestNoList);
        handleResult.setNeedAck(true);
        log.info("--批量交易-handle---end----------{}",json==null?"":json.toJSONString());
        return handleResult;
    }

    @Setter
    @Getter
    private static class BatchAsyncTransactionGatewayResponse {

        private static final String CALL_SUCCESS_CODE = "1";
        private static final String BUSINESS_SUCCESS_CODE = "SUCCESS";

        // 业务处理状态(处理失败 INIT;处理成功 SUCCESS),平台可根据非 SUCCESS 状态做相应处理,处理失败时可参考错误码
        private String status;
        // 错误码
        private String errorCode;
        // 错误码
        private String errorMessage;
        // 请求流水号
        private String asyncRequestNo;
        // 请求业务类型
        private String bizType;

        private boolean isBusinessSuccess() {
            return StringUtils.isNotBlank(status) && BUSINESS_SUCCESS_CODE.equals(status);
        }
    }
}
